/*
 * Copyright (C) 2000-2008 Jens Nixdorf and various contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies of the Software, its documentation and marketing & publicity
 * materials, and acknowledgment shall be given in the documentation, materials
 * and software packages that this Software was used.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package org.mopore.jat.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JWindow;

public class ImageMirror extends JWindow {
	
	private BufferedImage image;
	
	private Image offScreenImage = null;


	private RenderingHints rh;


	private AlphaComposite makeComposite(float alpha) {
		int type = AlphaComposite.SRC_OVER;
		return (AlphaComposite.getInstance(type, alpha));
	}

	
	public ImageMirror() throws Exception {
		initialize();
	}
	
	

	
	private void initialize() throws Exception {
		
		InputStream inputStream = 
			ImageMirror.class.getResourceAsStream( "/tray.gif" );
		
		this.image = ImageIO.read( inputStream );
		
		this.setSize(400, 200);
		this.setBackground(Color.WHITE);
		Toolkit t = this.getToolkit();
		this.setLocation(
			(int)((t.getScreenSize().getWidth() - this.getWidth())/2),
			(int)((t.getScreenSize().getHeight() - this.getHeight())/2)
		);		
		this.rh  = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
		this.setVisible(true);
	}
	
	public final void paint(Graphics g) {
		if (this.offScreenImage==null)
			this.offScreenImage =  this.createImage(this.getWidth(),this.getHeight());
		Graphics2D osG = (Graphics2D)this.offScreenImage.getGraphics();

		osG.setRenderingHints(rh);            
		render(osG);
		osG.dispose();
		g.drawImage(this.offScreenImage,0,0,this); 
	}

	protected void render(Graphics2D g){
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		
		final int imageWidth = image.getWidth();
		final int imageHeight = image.getHeight();
		
		Paint oldP = g.getPaint();
		
        g.setPaint( 
                new GradientPaint( 
                    0, 0, new Color( 0,0,0 ),
                    0, 120, new Color( 20,20,90  )
                )
            );
         g.fillRect( 0, 0, getWidth(), 90 );
		
		g.setPaint( oldP );
		
		g.setColor( Color.BLACK );
		g.fillRect(0,90,getWidth(),getHeight()-90);

		g.drawImage( image, 60, 30, imageWidth, imageHeight, null );
		
		BufferedImage newImage = reflectImage( image );
		newImage = mirrorImage( newImage );
		
		g.setComposite(makeComposite( 0.4f ));
		
		g.translate( -(imageWidth*1.5), 0 );
//		g.translate(60, 30+ imageHeight );
		g.shear( 1.0, 0.0 );
		
		g.drawImage( newImage, 60, 30 + imageHeight, imageWidth, imageHeight, null );
		
		g.shear( -1.0, 0.0 );
		g.setColor( new Color( 240, 240, 255 ) );
		g.setFont( new Font( "Arial", Font.PLAIN, 24 ));
		g.drawString( "image in clipboard", 300, 85);
	}

	private BufferedImage reflectImage( BufferedImage bImage ) {
		
        float opacity = 0.4f;
        float fadeHeight = 0.3f;
		
		int imageWidth = bImage.getWidth();
		int imageHeight = bImage.getHeight();
		
        BufferedImage reflection = new BufferedImage( imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB );
		Graphics2D rg = reflection.createGraphics();
        rg.drawRenderedImage( bImage, null );
		rg.setComposite( AlphaComposite.getInstance( AlphaComposite.DST_IN ) );
        rg.setPaint( 
            new GradientPaint( 
                0, imageHeight*fadeHeight, new Color( 0.0f, 0.0f, 0.0f, 0.0f ),
                0, imageHeight, new Color( 0.0f, 0.0f, 0.0f, opacity )
            )
        );
        rg.fillRect( 0, 0, imageWidth, imageHeight );
        rg.dispose();
		
		return reflection;
	}
	
	
	private BufferedImage mirrorImage( BufferedImage bImage ) {
		
		int w = bImage.getWidth();
		int h = bImage.getHeight();

		int x = 0;
		int y = 0;
		BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		
		Graphics2D g = bi.createGraphics();
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		

//		g.rotate(radians, w / 2, h / 2);

		g.scale( 1, -1 );
		g.translate(x, y);
		
		g.drawImage(bImage, 0, -h, w, h, null);

		g.dispose();

		return bi;
	}
	
	

	public static void main(String[] args) throws Exception {
		new ImageMirror().setVisible( true );

	}

}
